package com.junzhiit.nengji.app.service.impl;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.app.service.CouponsService;
import com.junzhiit.nengji.app.web.exception.ChainNotFoundException;
import com.junzhiit.nengji.app.web.exception.CouponsAlreadyExistsException;
import com.junzhiit.nengji.app.web.exception.CouponsNotFoundException;
import com.junzhiit.nengji.app.web.exception.RedeemcodeInsertException;
import com.junzhiit.nengji.app.web.exception.ShopNotFoundException;
import com.junzhiit.nengji.app.web.util.FileUtil;
import com.junzhiit.nengji.app.web.util.ViewObjectUtil;
import com.junzhiit.nengji.app.web.util.tools.NumberUtils;
import com.junzhiit.nengji.app.web.vo.CouponsAddVO;
import com.junzhiit.nengji.app.web.vo.CouponsEditVO;
import com.junzhiit.nengji.app.web.vo.CouponsSearchVO;
import com.junzhiit.nengji.app.web.vo.DataTablesParamVO;
import com.junzhiit.nengji.app.web.vo.ResultVO;
import com.junzhiit.nengji.app.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.dao.ChainDAO;
import com.junzhiit.nengji.dao.CouponsDAO;
import com.junzhiit.nengji.dao.RedeemCodeDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.UserCouponsDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Chain;
import com.junzhiit.nengji.model.Coupons;
import com.junzhiit.nengji.model.RedeemCode;
import com.junzhiit.nengji.model.Shop;
import com.junzhiit.nengji.model.UserCoupons;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.SystemUserType;

@Service
public class CouponsServiceImpl extends BaseServiceImpl implements CouponsService {

	@Autowired
	private CouponsDAO couponsDAO;

	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;

	@Autowired
	private ShopDAO shopDAO;
	
	@Autowired
	private ChainDAO chainDAO;
	
	@Autowired
	private RedeemCodeDAO redeemCodeDAO;
	
	@Value("${upload.mall.coupons.qrcode}")
	private String qrcodePath;

	@Value("${wap.event.coupons.page}")
	private String eventCoupons;
	
	@Autowired
	private UserCouponsDAO userCouponsDAO;
	
	@Override
	public Map<String, Object> findAll(DataTablesParamVO dtp, CouponsSearchVO couponsVO) {
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsVO.getSessionId()), SystemUserSessionVO.class);
		
		Coupons coupons = new Coupons();
		BeanUtils.copyProperties(couponsVO, coupons);
		
		if(systemUserSessionVO.getLoginType()!=null && systemUserSessionVO.getLoginType().intValue()==SystemUserType.SHOP.toIntStatus()){
			if(couponsVO.getIsChain() == null || Is.NO.toIntValue()==couponsVO.getIsChain()){
				//店铺
				Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
				if (shop == null) {
					throw new ShopNotFoundException("店铺不存在");
				}
				coupons.setShopId(shop.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}else if(Is.YES.toIntValue()==couponsVO.getIsChain()){
				//连锁品牌
				Chain chain=chainDAO.query(systemUserSessionVO.getSystemId());
				if(chain == null){
					throw new ChainNotFoundException("连锁品牌不存在");
				}
				coupons.setChainId(chain.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}
		}else if(systemUserSessionVO.getLoginType().intValue()==SystemUserType.INTERNAL.toIntStatus()){
			coupons.setPlatform(SystemUserType.INTERNAL.toIntStatus());
		}

		List<Coupons> list = couponsDAO.findAll(coupons, dtp.getStart(), dtp.getLength());
		int totalCount = couponsDAO.getTotalCount(coupons);

		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}

	@Override
	public ResultVO findById(String id) {
		ResultVO result = new ResultVO();
		Coupons coupons = couponsDAO.query(id);
		if (coupons == null) {
			throw new CouponsNotFoundException("优惠卷未找到");
		}
		result.setData(coupons);
		return result;
	}

	@Override
	public ResultVO add(CouponsAddVO couponsAddVO) {
		ResultVO result = new ResultVO();

		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsAddVO.getSessionId()), SystemUserSessionVO.class);
		
		Coupons coupons = new Coupons();
		BeanUtils.copyProperties(couponsAddVO, coupons);
		
		if(systemUserSessionVO.getLoginType().intValue()==SystemUserType.SHOP.toIntStatus()){
			
			if(couponsAddVO.getIsChain() == null || Is.NO.toIntValue()==couponsAddVO.getIsChain().intValue()){
				//店铺
				Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
				if (shop == null) {
					throw new ShopNotFoundException("店铺不存在");
				}
				coupons.setShopId(shop.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}else if(Is.YES.toIntValue()==couponsAddVO.getIsChain().intValue()){
				//连锁品牌
				Chain chain=chainDAO.query(systemUserSessionVO.getSystemId());
				if(chain == null){
					throw new ChainNotFoundException("连锁品牌不存在");
				}
				coupons.setChainId(chain.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}
			
		}else if(systemUserSessionVO.getLoginType().intValue()==SystemUserType.INTERNAL.toIntStatus()){
			coupons.setPlatform(SystemUserType.INTERNAL.toIntStatus());
		}
		coupons.setStatus(Is.YES.toIntValue());
		coupons.setPlatform(systemUserSessionVO.getLoginType());
		
		Coupons data = couponsDAO.insert(coupons);
		if(couponsAddVO.getIsLimitCount()==Is.YES.toIntValue()){
			Integer limitCount=couponsAddVO.getLimitCount();
			Integer length=10;
			List<String> codeList=NumberUtils.getStringRandom(limitCount, length);
			List<RedeemCode> rcList=new ArrayList<RedeemCode>();
			for(String code:codeList){
				RedeemCode rc=new RedeemCode();
				rc.setCode(code);
				rc.setCouponsId(data.getId());
				rc.setStatus(Is.NO.toIntValue());
				rcList.add(rc);
			}
			int i=redeemCodeDAO.batchInsert(rcList);
			if(i==1){
				throw new RedeemcodeInsertException("兑换码添加异常");
			}
		}
		result.setData(data);

		return result;
	}

	@Override
	public ResultVO edit(CouponsEditVO couponsEditVO) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsEditVO.getSessionId()), SystemUserSessionVO.class);
		Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
		if (shop == null) {
			throw new ShopNotFoundException("店铺不存在");
		}
		Coupons coupons = new Coupons();
		BeanUtils.copyProperties(couponsEditVO, coupons);
		coupons.setShopId(shop.getId());
		boolean data = couponsDAO.update(coupons);
		result.setData(data);
		return result;
	}

	@Override
	public ResultVO updateStatus(String id, Integer status) {
		ResultVO result = new ResultVO();

		Coupons coupons = new Coupons();
		coupons.setId(id);
		status = (status == 1) ? 1 : 0;
		coupons.setStatus(status);

		boolean data = couponsDAO.update(coupons);
		result.setData(data);

		return result;
	}

	@Override
	public ResultVO getCouponsList(String sessionId) {
		ResultVO result=new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(sessionId), SystemUserSessionVO.class);
		//平台单店及连锁品牌单店优惠券查询
		if(systemUserSessionVO.getIsChain() == Is.NO.toIntValue()){
			Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
			if (shop == null) {
				throw new ShopNotFoundException("店铺不存在");
			}
			result.setData(couponsDAO.getCouponsList(shop.getId(),Is.NO.toIntValue()));
		}
		//连锁品牌平台优惠券查询
		if(systemUserSessionVO.getIsChain() == Is.YES.toIntValue()){
			Chain chain = chainDAO.query(systemUserSessionVO.getSystemId());
			if (chain == null) {
				throw new ShopNotFoundException("品牌不存在");
			}
			result.setData(couponsDAO.getCouponsList(chain.getId(),Is.YES.toIntValue()));
		}
		
		return result;
	}

	@Override
	public void soldOutCoupons() {
		List<Coupons> coupons=couponsDAO.getCoupons(1);
		Date now = new Date();
		for(Coupons coupon : coupons){
			if(coupon.getUnderTime().getTime() <= now.getTime()){
				coupon.setStatus(0);
				couponsDAO.update(coupon);
			}
		}
	}
	
	public ResultVO createQRCode(String id) {
		ResultVO result = new ResultVO();

		String qrcodeName = id+"."+FileUtil.QR_CODE_FORMAT;
		String fullpath = qrcodePath+qrcodeName;
		
		if(StringUtils.isNotBlank(id)){
			File file = new File(fullpath);
			if (file.exists())
				FileUtil.removeFile(fullpath);
		}
		String content = eventCoupons+"?id="+id;
		
		FileUtil.createQRCode(content, fullpath);
		Map<String, String> data = new HashMap<String, String>();
		data.put("qrcodeName", qrcodeName);
		data.put("qrcodePath", content);
		result.setData(data);
		return result;
	}
	
	public void downloadQRCode(HttpServletRequest request,HttpServletResponse response,String qrcodeName,String couponsName) {
		try {
			String qrcode = qrcodePath+qrcodeName;
			String fileName = qrcodeName;
			
			//中文名乱码浏览器兼容
			String agent = request.getHeader("USER-AGENT");
			if (null != agent && -1 != agent.indexOf("MSIE") || null != agent  
			        && -1 != agent.indexOf("Trident")) {//IE
				fileName = java.net.URLEncoder.encode(fileName, "UTF-8");  
			}
			
			File file = new File(qrcode);
			if (file.exists())
				FileUtil.download(request, response, qrcode,fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public ResultVO insert(String userId, String couponsId) {
		ResultVO result = new ResultVO();
		Coupons coupons = couponsDAO.query(couponsId);
		UserCoupons userCoupons = userCouponsDAO.getUserCouponsByCouponsId(userId,couponsId);
		if(userCoupons!=null){
		  throw new CouponsAlreadyExistsException("该优惠劵已经领取过");
		}
		userCoupons = new UserCoupons();
		BeanUtils.copyProperties(coupons, userCoupons);
		if(coupons.getValidTimeState()==0){
		  userCoupons.setStartTime(coupons.getValidStartTime());
		  userCoupons.setEndTime(coupons.getValidEndTime());
		}else{
		  Date now=new Date();
		  Date date=DateUtil.addDays(now, coupons.getValidDays());
		  userCoupons.setStartTime(now);
		  userCoupons.setEndTime(date);
		}
		userCoupons.setStatus(Is.NO.toIntValue());
		userCoupons.setUserId(userId);
		userCoupons.setShopId(coupons.getShopId());
		userCoupons.setCouponsName(coupons.getName());
		userCoupons.setCouponsId(couponsId);
		userCoupons.setCouponsType(coupons.getType());
		if(coupons.getType()==0){
			//等于1为随机劵
			if(coupons.getIsOpenRandom()==1){
				//在条件为0.6,3的10万次测试中取Max、Min的比例为0.053%，在1-100区间内大于60的占30%
				Double offer =  this.randomWeights(coupons.getStartPrice(),coupons.getEndPrice(), 0.6,2);
				userCoupons.setPrice(offer);
			}else{
				userCoupons.setPrice(coupons.getPrice());
			}
	    }
	    result.setData(userCouponsDAO.insert(userCoupons));
	    return result;
	  }
		  
	
	  /**
	   * maxProportion：代表权重衡量的区间段的大小,取值为(0.1~0.9),值越大代表权重区间值越小即越接近于Max
	   * weights：权重,取值为(1~9),值越大代表在权重区间取值的比重越大
	   * */
	  private Double randomWeights(Double min,Double max,Double maxProportion,int weights){
	    weights = weights>=10 && weights<0 ?1:weights;
	    maxProportion = maxProportion>=1 && maxProportion<0 ?0.1:maxProportion;
	    Double median = (maxProportion*(max-min))+min;
	    Double result = new Double(0);
	    List<Double> list = new ArrayList<Double>();
	    for(int i = 1;i<=10;i++){
	      if(i<=weights){
	        list.add( (Math.random()*(max-median))+median);
	      }else{
	        list.add( (Math.random()*(median-min))+min);
	      }
	    }
	    result = list.get((int)(1+Math.random()*(10-1)));
	    return Double.parseDouble(new DecimalFormat("#.##").format(result));
	  }
}
